package com.fanghaoran.notes.service.impl;

import com.fanghaoran.notes.bean.*;
import com.fanghaoran.notes.dao.UserDao;
import com.fanghaoran.notes.dao.impl.UserDaoImpl;
import com.fanghaoran.notes.entity.*;
import com.fanghaoran.notes.dao.ProductDao;
import com.fanghaoran.notes.dao.impl.ProductDaoImpl;
import com.fanghaoran.notes.service.ProductService;
import com.fanghaoran.notes.util.Constants;
import com.fanghaoran.notes.util.StringUtil;
import org.quartz.CronExpression;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.ParseException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Author: win11
 * @Date: 2023/04/18/22:26
 * @Description:
 */
public class ProductServiceImpl implements ProductService {
    ProductDao productDao=new ProductDaoImpl();
    UserDao userDao=new UserDaoImpl();
    @Override
    public MyResult getProductPageByTid(int page, int pageSize, int tId,int orderBy) throws Exception {
        //获取总条数
        CountByTid count=productDao.selectTotalCountByTid(tId);
        //获取商品数据
        List<Product> products=null;
        //根据订单数排序
        if(orderBy==Constants.ORDER_BY_SALES){
            products=productDao.selectProductByTidOrderBySales(page,pageSize,tId);
        }else if(orderBy==Constants.ORDER_BY_SCORE){
            //根据评分
            products = productDao.selectProductByTidOrderByScore(page, pageSize, tId);
        }
        //用page封装起来,作为交给前端的总数据
        return new MyResult(Constants.NONEMPTY,new Page<>(products,page,pageSize,count.getCount()));
    }

    @Override
    public MyResult getProductPageByName(int page, int pageSize, String name,int orderBy) throws Exception {
        //获取总条数
        CountByName count=productDao.selectTotalCountByName(name);
        //获取商品数据
        List<Product> products=null;
        //根据订单数
        if(orderBy==Constants.ORDER_BY_SALES){
            products=productDao.selectProductByNameOrderBySales(page,pageSize,name);
        }else if(orderBy==Constants.ORDER_BY_SCORE){
            //根据评分
            products = productDao.selectProductByNameOrderByScore(page, pageSize, name);
        }
        //用page封装起来,作为交给前端的总数据
        return new MyResult(Constants.NONEMPTY,new Page<>(products,page,pageSize,count.getCount()));
    }

    @Override
    public MyResult getProductByPid(int pId) throws Exception {
        //数据库查询
        List<Product> products=productDao.selectProductByPid(pId);
        //返回
        return StringUtil.returnOfSelect(products);
    }

    @Override
    public MyResult setAsFavorite(int uId,int pId, int isFavorite) throws SQLException {
        Integer rows = productDao.insertFavorite(uId, pId, isFavorite);
        return StringUtil.returnOfUpdate(rows);
    }

    @Override
    public MyResult getFavoriteByUidAndPid(Integer uId, int pId) throws Exception {
        List<Favorite> favorites = productDao.selectFavoriteByUidAndPid(uId, pId);
        return StringUtil.returnOfSelect(favorites);
    }

    @Override
    public MyResult addProduct(int uId,String productName, BigDecimal price, int stock, String productInfo, int type, String productFile) throws SQLException {
        Integer rows = productDao.insertProduct(uId,productName, price, stock, productInfo, type, productFile);
        return StringUtil.returnOfUpdate(rows);
    }

    @Override
    public MyResult getProductByUid(Integer uId) throws Exception {
        List<Product> products = productDao.selectProductByUid(uId);
        return StringUtil.returnOfSelect(products);
    }

    @Override
    public MyResult modifyProduct(int pId, String pName, BigDecimal price, int stock, String pInfo) throws SQLException {
        Integer rows = productDao.updateProduct(pId, pName, price, stock, pInfo);
        return StringUtil.returnOfUpdate(rows);
    }

    @Override
    public MyResult getProductRank() throws Exception {
        List<Product> products = productDao.selectProductRank();
        return StringUtil.returnOfSelect(products);
    }

    @Override
    public MyResult modifyProductAfterBuy(int pid,int sales, int stock) throws SQLException {
        Integer rows = productDao.updateProductAfterBuy(pid,sales, stock);
        return StringUtil.returnOfUpdate(rows);
    }

    @Override
    public MyResult sendDiscount(int pId, int type, int amount) throws Exception {
        //先判断该类型的优惠券是否存在
        @SuppressWarnings("unchecked")
        List<Discount> discounts = (List<Discount>) showDiscountByPidAndTid(pId, type).getData();
        if(discounts==null) {
            Integer rows = productDao.addDiscount(pId, type, amount);
            return StringUtil.returnOfUpdate(rows);
        }else{
            int before = discounts.get(0).getDAmount();
            int after = before+amount;
            Integer rows = productDao.updateDiscount(pId, type, after);
            return StringUtil.returnOfUpdate(rows);
        }
    }

    @Override
    public MyResult showDiscount(int pId) throws Exception {
        List<DiscountDetail> discountDetails = productDao.selectDiscountByPid(pId);
        return StringUtil.returnOfSelect(discountDetails);
    }

    @Override
    public MyResult showUsageOfDiscount(int pId, int uId) throws Exception {
        List<DiscountUsage> discountUsages = productDao.selectUsageOfDiscount(pId, uId);
        return StringUtil.returnOfSelect(discountUsages);
    }

    @Override
    public MyResult addUsageOfDiscount(int pId, int uId, int tId, int dAmount, int dState) throws SQLException {
        Integer rows = productDao.insertUsageOfDiscount(pId, uId, tId, dAmount, dState);
        return StringUtil.returnOfUpdate(rows);
    }

    @Override
    public MyResult showDiscountByPidAndTid(int pId, int tId) throws Exception {
        List<Discount> discounts = productDao.selectDiscountByPidAndTid(pId,tId);
        return StringUtil.returnOfSelect(discounts);
    }

    @Override
    public MyResult modifyDiscount(int pId, int tId, int after) throws SQLException {
        Integer rows = productDao.updateDiscount(pId, tId, after);
        return StringUtil.returnOfUpdate(rows);
    }

    @Override
    public MyResult showDiscountUsageDetail(int pId, int uId) throws Exception {
        List<DiscountUsageDetail> discountUsageDetails = productDao.selectDiscountUsageDetail(pId, uId);
        return StringUtil.returnOfSelect(discountUsageDetails);
    }

    @Override
    public MyResult modifyUsageOfDiscount(int pId, int uId,int state) throws SQLException {
        Integer rows = productDao.updateUsageOfDiscount(pId, uId, state);
        return StringUtil.returnOfUpdate(rows);
    }

    @Override
    public MyResult modifyProductInTime(int pId, BigDecimal price, int stock, String scheduledTime) throws ParseException {
        //定时任务
        //时间字符串转换成cron表达式字符串
        String cronExpr = StringUtil.getCronExpression(scheduledTime);
        //创建cron对象
        CronExpression cron = new CronExpression(cronExpr);

        // 创建 ScheduledExecutorService 实例
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(20);

        // 创建任务
        Runnable task = () -> {
            // 修改产品库存和价格
            try {
                productDao.updateProductByPriceAndStock(pId,price,stock);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            System.out.println("当前修改产品时间: " + new Date());
        };

        // 计算下一次执行任务的时间
        Date nextRunTime = cron.getNextValidTimeAfter(new Date());

        // 计算当前时间与下一次执行任务的时间之间的时间差
        long initialDelay = nextRunTime.getTime() - System.currentTimeMillis();

        // 执行任务
        scheduler.scheduleAtFixedRate(task, initialDelay,  24*60*60 * 1000, TimeUnit.MILLISECONDS);
        return new MyResult(Constants.SUCCESS,null);
    }

    @Override
    public MyResult showInviteDetail(int pId, int uId) throws Exception {
        List<UserInvite> userInvites = productDao.selectInviteDetailByPidAndUid(pId, uId);
        return StringUtil.returnOfSelect(userInvites);
    }

    @Override
    public MyResult isInviteInValidTime(String inviteCode) throws Exception {
        List<UserInvite> userInvites = productDao.selectInviteDetailByInviteCode(inviteCode);
        if(!userInvites.isEmpty()){
            System.out.println(userInvites.get(0).getEndTime().isBefore(LocalDateTime.now()));
            //邀请码未过期
            if (userInvites.get(0).getEndTime().isAfter(LocalDateTime.now())) {
                return new MyResult(Constants.IS_VALID,null);
            }else{
                //已过期 修改邀请码状态
                int codeState=2;
                productDao.updateInviteCodeState(codeState,inviteCode);
                return new MyResult(Constants.NON_VALID,null);
            }
        }
        return new MyResult(Constants.EMPTY,null);
    }

    @Override
    public MyResult addInviteDetail(int pId, BigDecimal refundCount, String inviteCode, Integer uId) throws SQLException {
        //获取当前时间
        LocalDateTime beginTime=LocalDateTime.now();
        // 将LocalDateTime转为ZonedDateTime(带有时区)
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zonedDateTime = beginTime.atZone(zoneId);
        // 将ZonedDateTime加24小时
        ZonedDateTime zonedDateTimePlus24Hours = zonedDateTime.plusHours(24);
        // 获取失效时间
        LocalDateTime endTime = zonedDateTimePlus24Hours.toLocalDateTime();
        //状态
        int codeState=0;
        //数据库插入
        Integer rows = productDao.insertInviteDetail(pId, uId, inviteCode, refundCount, codeState, beginTime, endTime);
        return StringUtil.returnOfUpdate(rows);
    }

    @Override
    public MyResult modifyInviteState(int pId, Integer uId, int codeState) throws SQLException {
        Integer rows = productDao.updateInviteCodeStateByPidAndUid(pId, uId, codeState);
        return StringUtil.returnOfUpdate(rows);
    }

    @Override
    public MyResult checkQualification(Integer uId, String inviteCode) throws Exception {
        //检查是否为新用户
        //获取注册时间
        List<User> users = userDao.selectUserByUid(uId);
        Duration duration=Duration.between(LocalDateTime.now(),users.get(0).getRegisterTime());
        // 判断间隔是否超过一周
        if (duration.toDays() > 7) {
            return new MyResult(Constants.FAIL,"您不是新用户哦");
        } else {
            //判断邀请码状态是否存在以及使用情况
            List<UserInvite> userInvites = productDao.selectInviteDetailByInviteCode(inviteCode);
            if(userInvites.isEmpty()||userInvites.get(0).getCodeState()!=0){
                //不存在或者已被使用过
                return new MyResult(Constants.FAIL,"邀请码不存在或已被使用过");
            }else{
                //合格 更新邀请码表
                int codeState=1;
                productDao.updateInviteDetail(uId,codeState,inviteCode);
                return new MyResult(Constants.SUCCESS,"助力成功");
            }
        }

    }


}
